CNV
new.cluster.ids <- c("cancer", #0
"cancer", #1
"CAF", #2
"cancer", #3
"Endothelial", #4
"cancer", #5
"cancer", #6
"CAF", #7
"CAF", #8
"CAF", #9
"cancer", #10
"CAF", #11
"cancer", #12
"cancer", #13
"cancer", #14
"cancer", #15
"cancer", #16
"WBC", #17
"CAF" #18
)
#rename idents:
acc_all_cells = SetIdent(object = acc_all_cells,value = "RNA_snn_res.1") #active snn graph
names(new.cluster.ids) <- levels(acc_all_cells) #add snn graph levels to new.cluster.ids
acc_all_cells@meta.data[["seurat_clusters"]] = acc_all_cells@meta.data[["RNA_snn_res.1"]]
acc_all_cells = SetIdent(object = acc_all_cells,value = "seurat_clusters")
acc_all_cells <- RenameIdents(acc_all_cells, new.cluster.ids)
# divide "cancer" into patients:
cell_types = acc_all_cells@active.ident %>% as.data.frame()
cell_types[,1]<- as.character(cell_types[,1])
cell_types = cbind(cell_types,acc_all_cells$patient.ident) %>% setnames(old = names(.),
new = c('cell_type','patient'))
cell_types[cell_types$cell_type == "cancer",] = cell_types[cell_types$cell_type == "cancer",2]
# hmsc_rows = (startsWith(x = rownames(cell_types),prefix = "ACC.plate2") | startsWith(x = rownames(cell_types),prefix = "ACC1.")) & cell_types[,1] == "cancer"
# acc_rows = !(startsWith(x = rownames(cell_types),prefix = "ACC.plate2") | startsWith(x = rownames(cell_types),prefix = "ACC1.")) & cell_types[,1] == "cancer"
# cell_types[,1][hmsc_rows] = "HMSC"
# cell_types[,1][acc_rows] = "ACC"
#add to metadata:
cell_types[,2] = NULL
cell_types[cell_types$cell_type == "ACC1",] = "HMSC"
acc_all_cells = AddMetaData(object =acc_all_cells ,metadata = cell_types,col.name = "cell.type")

Original score
original_myo_genes = c( "TP63", "TP73", "CAV1", "CDH3", "KRT5", "KRT14", "ACTA2", "TAGLN", "MYLK", "DKK3")
original_lum_genes = c("KIT", "EHF", "ELF5", "KRT7", "CLDN3", "CLDN4", "CD24", "LGALS3", "LCN2", "SLPI" )
myoscore=apply(all_acc_cancer_cells@assays[["RNA"]][original_myo_genes,],2,mean)
lescore=apply(all_acc_cancer_cells@assays[["RNA"]][original_lum_genes,],2,mean)
all_acc_cancer_cells=AddMetaData(all_acc_cancer_cells,lescore-myoscore,"luminal_over_myo")
FeaturePlot(object = all_acc_cancer_cells,features = "luminal_over_myo")

data = FetchData(object = all_acc_cancer_cells,vars = "luminal_over_myo")
print(
data %>%
ggplot(aes( x=luminal_over_myo)) +
geom_density()
)

myoscore=apply(acc1_cancer_cells@assays[["RNA"]][original_myo_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]][original_lum_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "luminal_over_myo")

data = FetchData(object = acc1_cancer_cells,vars = "luminal_over_myo")
print(
data %>%
ggplot(aes( x=luminal_over_myo)) +
geom_density()
)

0.35 Most correlated score
Myo genes
myo_protein_markers = c("CNN1", "TP63","ACTA2")
top_myo = top_correlated(dataset = acc1_cancer_cells, genes = myo_protein_markers,threshold = 0.35)
print("Number of genes = " %>% paste(length(top_myo)))
[1] "Number of genes = 20"
message("Names of genes:")
Names of genes:
top_myo %>% head(30)
[1] "COL16A1" "RP1-39G22.4" "ACTG2" "CD200" "MYLK" "TP63" "KCNMB1" "ADAMTS2" "LOXL2"
[10] "TPM2" "CLIC3" "SNCG" "ACTA2" "TAGLN" "A2M" "NGFR" "CNN1" "PPP1R14A"
[19] "MYL9" "POM121L9P"
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_myo,original_myo_genes)
[1] "MYLK" "TP63" "ACTA2" "TAGLN"
myo_enrich_res = genes_vec_enrichment(genes = top_myo,background = rownames(acc1_cancer_cells),homer = T,title = "myo top enrichment",custom_pathways = luminal_gs)

myo_enrich_res
Lum genes
lum_protein_markers = c("KIT")
top_lum = top_correlated(dataset = acc1_cancer_cells, genes = lum_protein_markers,threshold = 0.35)
Warning in cor(expression %>% t(), markers_average) :
the standard deviation is zero
print("Number of genes = " %>% paste(length(top_lum)))
[1] "Number of genes = 22"
message("Names of genes:")
Names of genes:
top_lum %>% head(30)
[1] "FBXO44" "USP48" "MPC2" "SLC19A2" "ATL2" "B3GNT2" "AC093162.5"
[8] "MAP2" "KIT" "GLRB" "EFNA5" "PCDHGB7" "SLC29A1" "SASH1"
[15] "ALDH3B2" "CCND1" "RP11-254B13.1" "VSIG10" "NDFIP2" "SUSD6" "SPPL2A"
[22] "DSC2"
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_lum,original_lum_genes)
[1] "KIT"
lum_enrich_res = genes_vec_enrichment(genes = top_lum,background = rownames(acc1_cancer_cells),homer = T,title = "lum top enrichment",custom_pathways = luminal_gs)

lum_enrich_res
enriched genes score
rownames(lum_enrich_res) = lum_enrich_res$pathway_name
lum_enriched_genes = lum_enrich_res[1,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,lum_protein_markers) #add original markers
rownames(myo_enrich_res) = myo_enrich_res$pathway_name
myo_enriched_genes = myo_enrich_res[1,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,myo_protein_markers) #add original markers
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[myo_enriched_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[lum_enriched_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")

data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
data %>%
ggplot(aes( x=enriched_luminal_over_myo)) +
geom_density()
)

0.2 Most correlated score
myo Genes
myo_protein_markers = c("CNN1", "TP63","ACTA2")
top_myo = top_correlated(dataset = acc1_cancer_cells, genes = myo_protein_markers,threshold = 0.2)
print("Number of genes = " %>% paste(length(top_myo)))
[1] "Number of genes = 473"
message("Names of genes:")
Names of genes:
top_myo %>% head(30)
[1] "MIR429" "EXOSC10" "PLOD1" "TNFRSF8" "PDPN" "FBLIM1" "RP11-276H7.3"
[8] "HSPG2" "EPHA8" "IFNLR1" "GRHL3" "RP3-426I6.6" "SDC3" "RP11-490K7.1"
[15] "RP11-73M7.1" "TINAGL1" "COL16A1" "RP1-117O3.2" "RP11-435D7.3" "RP1-39G22.4" "SCMH1"
[22] "RP5-850O15.4" "RP5-866L20.3" "NEXN" "RP4-714D9.2" "RP5-837M10.3" "RP5-964H19.1" "CSF1"
[29] "RP11-498A13.1" "RP11-96K19.2"
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_myo,original_myo_genes)
[1] "MYLK" "TP63" "ACTA2" "DKK3" "TAGLN" "CDH3"
myo_enrich_res = genes_vec_enrichment(genes = top_myo,background = rownames(acc1_cancer_cells),homer = T,title = "myo top enrichment",custom_pathways = luminal_gs)

myo_enrich_res
Lum Genes
lum_protein_markers = c("KIT")
top_lum = top_correlated(dataset = acc1_cancer_cells, genes = lum_protein_markers,threshold = 0.2)
Warning in cor(expression %>% t(), markers_average) :
the standard deviation is zero
print("Number of genes = " %>% paste(length(top_lum)))
[1] "Number of genes = 1535"
message("Names of genes:")
Names of genes:
top_lum %>% head(30)
[1] "RP11-206L10.11" "HES4" "RP11-54O7.18" "CPTP" "RP3-395M20.8" "TNFRSF14" "RPL22"
[8] "ICMT" "ERRFI1" "RERE" "H6PD" "TMEM201" "NMNAT1" "UBE4B"
[15] "APITD1-CORT" "CENPS" "RP4-635E18.7" "FBXO2" "FBXO44" "UQCRHL" "MST1P2"
[22] "SDHB" "PADI2" "ARHGEF10L" "AKR7A2" "TMCO4" "EIF4G3" "USP48"
[29] "NIPAL3" "PIGV"
message("Genes that also apeared in the original score:")
Genes that also apeared in the original score:
intersect(top_lum,original_lum_genes)
[1] "KIT" "EHF" "LGALS3"
lum_enrich_res = genes_vec_enrichment(genes = top_lum,background = rownames(acc1_cancer_cells),homer = T,title = "lum top enrichment",custom_pathways = luminal_gs)

lum_enrich_res
enriched genes
rownames(lum_enrich_res) = lum_enrich_res$pathway_name
lum_enriched_genes = lum_enrich_res[3,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,lum_protein_markers) #add original markers
rownames(myo_enrich_res) = myo_enrich_res$pathway_name
myo_enriched_genes = myo_enrich_res[3,"geneID"] %>% strsplit(split = "/") %>% .[[1]] %>% c(.,myo_protein_markers) #add original markers
message("genes in myo score:")
genes in myo score:
myo_enriched_genes
[1] "FBLIM1" "NEXN" "NMNAT2" "MYLK" "CCDC50" "IGFBP7" "RAI14" "ARAP3" "SPARC" "CALD1" "LOXL2" "COL5A1"
[13] "ACTA2" "DKK3" "MSRB3" "COL4A1" "ACTN1" "TPM1" "TGFB1I1" "ADORA2B" "MXRA7" "CNN1" "TP63" "ACTA2"
message("genes in lum score:")
genes in lum score:
lum_enriched_genes
[1] "PADI2" "PATJ" "PEX11B" "APH1A" "C1orf43" "EFNA4" "NECTIN4" "SCYL3" "ELF3"
[10] "SOX13" "IRF6" "MED28" "EPB41L4A" "RGL2" "C6orf132" "TPD52L1" "ICA1" "MACC1"
[19] "TRPS1" "FAM83H" "RASEF" "ARRDC1" "COMMD3" "ANK3" "GSTO2" "PDCD4" "EHF"
[28] "ALDH3B2" "SHANK2" "SORL1" "FKBP4" "PTPN6" "DUSP16" "RERG" "ADCY6" "ERBB3"
[37] "ERP29" "SUSD6" "RPS6KA5" "SPINT1" "FEM1B" "TLE3" "SCAMP2" "CLN3" "ADGRG1"
[46] "ATP2C2" "GGT6" "MYO1D" "ST6GALNAC2" "CYB5A" "BLVRB" "VRK3" "SYCP2" "TMPRSS2"
[55] "LIMK2" "KIT"
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[myo_enriched_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[lum_enriched_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")

data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
data %>%
ggplot(aes( x=enriched_luminal_over_myo)) +
geom_density()
)

enriched genes and in original score
myo_enriched_genes = myo_enriched_genes[myo_enriched_genes %in% original_myo_genes]
lum_enriched_genes = lum_enriched_genes[lum_enriched_genes %in% original_lum_genes]
message("genes in myo score:")
genes in myo score:
myo_enriched_genes
[1] "MYLK" "ACTA2" "DKK3" "TP63" "ACTA2"
message("genes in lum score:")
genes in lum score:
lum_enriched_genes
[1] "EHF" "KIT"
myoscore=apply(acc1_cancer_cells@assays[["RNA"]]@data[myo_enriched_genes,],2,mean)
lescore=apply(acc1_cancer_cells@assays[["RNA"]]@data[lum_enriched_genes,],2,mean)
acc1_cancer_cells=AddMetaData(acc1_cancer_cells,lescore-myoscore,"enriched_luminal_over_myo")
FeaturePlot(object = acc1_cancer_cells,features = "enriched_luminal_over_myo")

data = FetchData(object = acc1_cancer_cells,vars = "enriched_luminal_over_myo")
print(
data %>%
ggplot(aes( x=enriched_luminal_over_myo)) +
geom_density()
)

LS0tCnRpdGxlOiAiVGl0bGUiCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQotLS0KCiMjIERhdGEKCmBgYHtyfQphY2MxX2NhbmNlcl9jZWxscyA9IHJlYWRSRFMoIi4vRGF0YS9hY2MxX2NhbmNlcl9jZWxsc18xNUtuQ291bnRfVjMuUkRTIikKYWxsX2FjY19jYW5jZXJfY2VsbHMgPSByZWFkUkRTKCIuL0RhdGEvYWNjX2NhbmNlcl9jZWxsc19WMy5SRFMiKQphY2NfYWxsX2NlbGxzID0gcmVhZFJEUygiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX3dpdGhfQUNDMV8uUkRTIikKbHVtaW5hbF9wYXRod2F5cyA9IGMoIkNIQVJBRkVfQlJFQVNUX0NBTkNFUl9MVU1JTkFMX1ZTX0JBU0FMX0ROIiwiQ0hBUkFGRV9CUkVBU1RfQ0FOQ0VSX0xVTUlOQUxfVlNfQkFTQUxfVVAiLCJDSEFSQUZFX0JSRUFTVF9DQU5DRVJfTFVNSU5BTF9WU19NRVNFTkNIWU1BTF9ETiIsIkNIQVJBRkVfQlJFQVNUX0NBTkNFUl9MVU1JTkFMX1ZTX01FU0VOQ0hZTUFMX1VQIiwiSFVQRVJfQlJFQVNUX0JBU0FMX1ZTX0xVTUlOQUxfRE4iLCJMSU1fTUFNTUFSWV9MVU1JTkFMX1BST0dFTklUT1JfVVAiLCJTTUlEX0JSRUFTVF9DQU5DRVJfTFVNSU5BTF9CX1VQIiApCgojIGFkZCBsdW1pbmFsIHBhdGh3YXlzCmx1bWluYWxfZ3MgPSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIikgJT4lYXMuZGF0YS5mcmFtZSgpICU+JSBkcGx5cjo6ZmlsdGVyKGdzX25hbWUgJWluJSBsdW1pbmFsX3BhdGh3YXlzKSU+JSBkcGx5cjo6ZGlzdGluY3QoZ3NfbmFtZSwgZ2VuZV9zeW1ib2wpICU+JSBhcy5kYXRhLmZyYW1lKCkKCmBgYAoKIyMgUGFyYW1ldGVycwoKYGBge3Igd2FybmluZz1GQUxTRX0Kc3VmZml4ID0gIjAxXzIyIgpkYXRhX3RvX3JlYWQgPSAiIgpgYGAKCgojIyBmdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiREVHX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjIuMSIpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiSE1TQ19mdW5jdGlvbnMiLHZlcnNpb24gPSAiMC4xLjAiLHNjcmlwdF9uYW1lID0gImZ1bmN0aW9ucy5SIikKYGBgCgoKIyBNWUIgZXhwcmVzc2lvbgoKYGBge3IgZmlnLndpZHRoPTEwfQphbGxfYWNjX2NhbmNlcl9jZWxscyA9IFNldElkZW50KG9iamVjdCA9IGFsbF9hY2NfY2FuY2VyX2NlbGxzLHZhbHVlID0gInBhdGllbnQuaWRlbnQiKSAjYWN0aXZlIHNubiBncmFwaApGZWF0dXJlUGxvdChvYmplY3QgPSBhbGxfYWNjX2NhbmNlcl9jZWxscyxmZWF0dXJlcyA9ICJNWUIiLGxhYmVsID0gVCkKYGBgCiMgQ05WCgpgYGB7cn0KI3NldCBjZWxsIHR5cGVzCm5ldy5jbHVzdGVyLmlkcyA8LSBjKCJjYW5jZXIiLCAjMAogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzEKICAgICAgICAgICAgICAgICAgICAgIkNBRiIsICMyCiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMwogICAgICAgICAgICAgICAgICAgICAiRW5kb3RoZWxpYWwiLCAjNAogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzUKICAgICAgICAgICAgICAgICAgICAgImNhbmNlciIsICM2CiAgICAgICAgICAgICAgICAgICAgICJDQUYiLCAjNwogICAgICAgICAgICAgICAgICAgICAiQ0FGIiwgIzgKICAgICAgICAgICAgICAgICAgICAgIkNBRiIsICM5CiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMTAKICAgICAgICAgICAgICAgICAgICAgIkNBRiIsICMxMQogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzEyCiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMTMKICAgICAgICAgICAgICAgICAgICAgImNhbmNlciIsICMxNAogICAgICAgICAgICAgICAgICAgICAiY2FuY2VyIiwgIzE1CiAgICAgICAgICAgICAgICAgICAgICJjYW5jZXIiLCAjMTYKICAgICAgICAgICAgICAgICAgICAgIldCQyIsICMxNwogICAgICAgICAgICAgICAgICAgICAiQ0FGIiAjMTgKICAgICAgICAgICAgICAgICAgICAgKQpgYGAKCgpgYGB7ciBmaWcuc2hvdz0naGlkZSd9CiNyZW5hbWUgaWRlbnRzOgphY2NfYWxsX2NlbGxzID0gU2V0SWRlbnQob2JqZWN0ID0gYWNjX2FsbF9jZWxscyx2YWx1ZSA9ICJSTkFfc25uX3Jlcy4xIikgI2FjdGl2ZSBzbm4gZ3JhcGgKbmFtZXMobmV3LmNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoYWNjX2FsbF9jZWxscykgI2FkZCBzbm4gZ3JhcGggbGV2ZWxzIHRvIG5ldy5jbHVzdGVyLmlkcwphY2NfYWxsX2NlbGxzQG1ldGEuZGF0YVtbInNldXJhdF9jbHVzdGVycyJdXSA9IGFjY19hbGxfY2VsbHNAbWV0YS5kYXRhW1siUk5BX3Nubl9yZXMuMSJdXQphY2NfYWxsX2NlbGxzID0gU2V0SWRlbnQob2JqZWN0ID0gYWNjX2FsbF9jZWxscyx2YWx1ZSA9ICJzZXVyYXRfY2x1c3RlcnMiKQphY2NfYWxsX2NlbGxzIDwtIFJlbmFtZUlkZW50cyhhY2NfYWxsX2NlbGxzLCBuZXcuY2x1c3Rlci5pZHMpIAoKIyBkaXZpZGUgImNhbmNlciIgaW50byBwYXRpZW50czoKY2VsbF90eXBlcyA9IGFjY19hbGxfY2VsbHNAYWN0aXZlLmlkZW50ICU+JSBhcy5kYXRhLmZyYW1lKCkKY2VsbF90eXBlc1ssMV08LSBhcy5jaGFyYWN0ZXIoY2VsbF90eXBlc1ssMV0pCmNlbGxfdHlwZXMgPSBjYmluZChjZWxsX3R5cGVzLGFjY19hbGxfY2VsbHMkcGF0aWVudC5pZGVudCkgJT4lIHNldG5hbWVzKG9sZCA9IG5hbWVzKC4pLCAKICAgICAgICAgbmV3ID0gYygnY2VsbF90eXBlJywncGF0aWVudCcpKQpjZWxsX3R5cGVzW2NlbGxfdHlwZXMkY2VsbF90eXBlID09ICJjYW5jZXIiLF0gPSBjZWxsX3R5cGVzW2NlbGxfdHlwZXMkY2VsbF90eXBlID09ICJjYW5jZXIiLDJdCgoKIyBobXNjX3Jvd3MgPSAoc3RhcnRzV2l0aCh4ID0gcm93bmFtZXMoY2VsbF90eXBlcykscHJlZml4ID0gIkFDQy5wbGF0ZTIiKSB8IHN0YXJ0c1dpdGgoeCA9IHJvd25hbWVzKGNlbGxfdHlwZXMpLHByZWZpeCA9ICJBQ0MxLiIpKSAmIGNlbGxfdHlwZXNbLDFdID09ICJjYW5jZXIiIAojIGFjY19yb3dzID0gIShzdGFydHNXaXRoKHggPSByb3duYW1lcyhjZWxsX3R5cGVzKSxwcmVmaXggPSAiQUNDLnBsYXRlMiIpIHwgc3RhcnRzV2l0aCh4ID0gcm93bmFtZXMoY2VsbF90eXBlcykscHJlZml4ID0gIkFDQzEuIikpICYgY2VsbF90eXBlc1ssMV0gPT0gImNhbmNlciIgCiMgY2VsbF90eXBlc1ssMV1baG1zY19yb3dzXSAgPSAiSE1TQyIKIyBjZWxsX3R5cGVzWywxXVthY2Nfcm93c10gID0gIkFDQyIKCiNhZGQgdG8gbWV0YWRhdGE6CmNlbGxfdHlwZXNbLDJdID0gTlVMTCAKY2VsbF90eXBlc1tjZWxsX3R5cGVzJGNlbGxfdHlwZSA9PSAiQUNDMSIsXSA9ICJITVNDIgphY2NfYWxsX2NlbGxzID0gQWRkTWV0YURhdGEob2JqZWN0ID1hY2NfYWxsX2NlbGxzICxtZXRhZGF0YSA9IGNlbGxfdHlwZXMsY29sLm5hbWUgPSAiY2VsbC50eXBlIikKYGBgCgpgYGB7ciBmaWcud2lkdGg9MTB9CmxpYnJhcnkoaW5mZXJjbnYpCmxpYnJhcnkodGlkeXZlcnNlKQphY2NfYW5ub3RhdGlvbiAgPSBhcy5kYXRhLmZyYW1lKGFjY19hbGxfY2VsbHNAbWV0YS5kYXRhWywiY2VsbC50eXBlIixkcm9wID0gRl0pCmFjY19hbm5vdGF0aW9uID0gYWNjX2Fubm90YXRpb24gJT4lIHJvd25hbWVzX3RvX2NvbHVtbigib3JpZy5pZGVudCIpIAphY2NfYW5ub3RhdGlvbiA9IGFjY19hbm5vdGF0aW9uICU+JSBtdXRhdGUob3JpZy5pZGVudCA9IGdzdWIoeCA9IGFjY19hbm5vdGF0aW9uJG9yaWcuaWRlbnQscGF0dGVybiA9ICJcXC4iLCByZXBsYWNlbWVudCA9ICItIikgJT4lIAogIGdzdWIocGF0dGVybiA9ICJfIiwgcmVwbGFjZW1lbnQgPSAiLSIpKQogIAoKd3JpdGUudGFibGUoYWNjX2Fubm90YXRpb24sICIuL0RhdGEvaW5mZXJDTlYvYWNjX2Fubm90YXRpb24udHh0IiwgYXBwZW5kID0gRkFMU0UsIAogICAgICAgICAgICBzZXAgPSAiXHQiLCBkZWMgPSAiLiIscm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IEYpCgppbmZlcmNudl9vYmogPSBDcmVhdGVJbmZlcmNudk9iamVjdChyYXdfY291bnRzX21hdHJpeD0iLi9EYXRhL2luZmVyQ05WL2FsbC40aWNudi50eHQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnNfZmlsZT0iLi9EYXRhL2luZmVyQ05WL2FjY19hbm5vdGF0aW9uLnR4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGltPSJcdCIsZ2VuZV9vcmRlcl9maWxlPSIuL0RhdGEvaW5mZXJDTlYvZ2VuY29kZV92MTlfZ2VuZV9wb3MudHh0IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAscmVmX2dyb3VwX25hbWVzPWMoIkNBRiIsICJFbmRvdGhlbGlhbCIsICJXQkMiKSkgI2dyb3VwcyBvZiBub3JtYWwgY2VsbHMKCmluZmVyY252X29ial9kZWZhdWx0ID0gaW5mZXJjbnY6OnJ1bihpbmZlcmNudl9vYmosIGN1dG9mZj0xLCBvdXRfZGlyPScuL0RhdGEvaW5mZXJDTlYvaW5mZXJjbnZfb3V0cHV0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfYnlfZ3JvdXBzPVQsIHBsb3Rfc3RlcHM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZW5vaXNlPVRSVUUsIEhNTT1GQUxTRSwgbm9fcHJlbGltX3Bsb3Q9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBuZ19yZXM9MzAwKQpwbG90X2NudihpbmZlcmNudl9vYmpfZGVmYXVsdCwgb3V0cHV0X2Zvcm1hdCA9ICJwbmciLCAgd3JpdGVfZXhwcl9tYXRyaXggPSBGQUxTRSxvdXRfZGlyID0gIi4vRGF0YS9pbmZlckNOVi8iLHBuZ19yZXMJPTgwMCxvYnNfdGl0bGUgPSAiTWFsaWduYW50IGNlbGxzIixyZWZfdGl0bGUgPSAiTm9ybWFsIGNlbGxzIikKCgpjbHVzdGVyLmluZm89RmV0Y2hEYXRhKGFjY19hbGxfY2VsbHMsYygiaWRlbnQiLCJvcmlnLmlkZW50IiwiVU1BUF8xIiwiVU1BUF8yIiwibkNvdW50X1JOQSIsIm5GZWF0dXJlX1JOQSIsInBlcmNlbnQubXQiLCJwYXRpZW50LmlkZW50Iiwic2V1cmF0X2NsdXN0ZXJzIikpCmNsdXN0ZXIuaW5mbyRjZWxsPXJvd25hbWVzKGNsdXN0ZXIuaW5mbykKCmxpYnJhcnkobGltbWEpCnNtb290aGVkPWFwcGx5KGluZmVyY252X29ial9kZWZhdWx0QGV4cHIuZGF0YSwyLHRyaWN1YmVNb3ZpbmdBdmVyYWdlLCBzcGFuPTAuMDEpCmNuc2lnPXNxcnQoYXBwbHkoKHNtb290aGVkLTEpXjIsMixtZWFuKSkKdW1hcD1jbHVzdGVyLmluZm8KbmFtZXMoY25zaWcpPXVtYXAkY2VsbAoKYWNjX2FsbF9jZWxscyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSBhY2NfYWxsX2NlbGxzLCBtZXRhZGF0YSA9IGNuc2lnLCBjb2wubmFtZSA9ICJjb3B5bnVtYmVyIikKYWNjX2FsbF9jZWxscyA9IFNldElkZW50KG9iamVjdCA9IGFjY19hbGxfY2VsbHMsdmFsdWUgPSAiY2VsbC50eXBlIikKRmVhdHVyZVBsb3QoYWNjX2FsbF9jZWxscywgImNvcHludW1iZXIiLHB0LnNpemUgPSAxLCBjb2xzID0gYygibGlnaHRibHVlIiwib3JhbmdlIiwicmVkIiwiZGFya3JlZCIpLGxhYmVsID0gVCxyZXBlbCA9IFQpCmBgYAoKCgohW0NOViBwbG90XSgvc2NpL2xhYnMveW90YW1kL2xhYl9zaGFyZS9hdmlzaGFpLndpemVsL1JfcHJvamVjdHMvSE1TQy9EYXRhL2luZmVyQ05WL2luZmVyY252LnBuZykKCiMjIE9yaWdpbmFsIHNjb3JlCmBgYHtyfQpvcmlnaW5hbF9teW9fZ2VuZXMgPSBjKCAiVFA2MyIsICJUUDczIiwgIkNBVjEiLCAiQ0RIMyIsICJLUlQ1IiwgIktSVDE0IiwgIkFDVEEyIiwgIlRBR0xOIiwgIk1ZTEsiLCAiREtLMyIpCm9yaWdpbmFsX2x1bV9nZW5lcyA9IGMoIktJVCIsICJFSEYiLCAiRUxGNSIsICJLUlQ3IiwgIkNMRE4zIiwgIkNMRE40IiwgIkNEMjQiLCAiTEdBTFMzIiwgIkxDTjIiLCAiU0xQSSIgKQpgYGAKCmBgYHtyfQpteW9zY29yZT1hcHBseShhbGxfYWNjX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1bb3JpZ2luYWxfbXlvX2dlbmVzLF0sMixtZWFuKQpsZXNjb3JlPWFwcGx5KGFsbF9hY2NfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXVtvcmlnaW5hbF9sdW1fZ2VuZXMsXSwyLG1lYW4pCmFsbF9hY2NfY2FuY2VyX2NlbGxzPUFkZE1ldGFEYXRhKGFsbF9hY2NfY2FuY2VyX2NlbGxzLGxlc2NvcmUtbXlvc2NvcmUsImx1bWluYWxfb3Zlcl9teW8iKQpGZWF0dXJlUGxvdChvYmplY3QgPSBhbGxfYWNjX2NhbmNlcl9jZWxscyxmZWF0dXJlcyA9ICJsdW1pbmFsX292ZXJfbXlvIikKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhbGxfYWNjX2NhbmNlcl9jZWxscyx2YXJzID0gImx1bWluYWxfb3Zlcl9teW8iKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PWx1bWluYWxfb3Zlcl9teW8pKSArIAogIGdlb21fZGVuc2l0eSgpIAopCmBgYAoKYGBge3J9Cm15b3Njb3JlPWFwcGx5KGFjYzFfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXVtvcmlnaW5hbF9teW9fZ2VuZXMsXSwyLG1lYW4pCmxlc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dW29yaWdpbmFsX2x1bV9nZW5lcyxdLDIsbWVhbikKYWNjMV9jYW5jZXJfY2VsbHM9QWRkTWV0YURhdGEoYWNjMV9jYW5jZXJfY2VsbHMsbGVzY29yZS1teW9zY29yZSwibHVtaW5hbF9vdmVyX215byIpCkZlYXR1cmVQbG90KG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLGZlYXR1cmVzID0gImx1bWluYWxfb3Zlcl9teW8iKQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAibHVtaW5hbF9vdmVyX215byIpCnByaW50KAogICAgZGF0YSAlPiUgCiAgICBnZ3Bsb3QoYWVzKCB4PWx1bWluYWxfb3Zlcl9teW8pKSArIAogICAgZ2VvbV9kZW5zaXR5KCkgCiAgKQpgYGAKCiMjIDAuMzUgTW9zdCBjb3JyZWxhdGVkIHNjb3JlIHsudGFic2V0fQoKIyMjIE15byBnZW5lcwoKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIGNvbGxhcHNlPVR9Cm15b19wcm90ZWluX21hcmtlcnMgPSBjKCJDTk4xIiwgIlRQNjMiLCJBQ1RBMiIpCnRvcF9teW8gID0gdG9wX2NvcnJlbGF0ZWQoZGF0YXNldCA9IGFjYzFfY2FuY2VyX2NlbGxzLCBnZW5lcyA9IG15b19wcm90ZWluX21hcmtlcnMsdGhyZXNob2xkID0gMC4zNSkKcHJpbnQoIk51bWJlciBvZiBnZW5lcyA9ICIgJT4lIHBhc3RlKGxlbmd0aCh0b3BfbXlvKSkpCm1lc3NhZ2UoIk5hbWVzIG9mIGdlbmVzOiIpCnRvcF9teW8gJT4lIGhlYWQoMzApCm1lc3NhZ2UoIkdlbmVzIHRoYXQgYWxzbyBhcGVhcmVkIGluIHRoZSBvcmlnaW5hbCBzY29yZToiKQppbnRlcnNlY3QodG9wX215byxvcmlnaW5hbF9teW9fZ2VuZXMpIApgYGAKYGBge3J9Cm15b19lbnJpY2hfcmVzID0gZ2VuZXNfdmVjX2VucmljaG1lbnQoZ2VuZXMgPSB0b3BfbXlvLGJhY2tncm91bmQgPSByb3duYW1lcyhhY2MxX2NhbmNlcl9jZWxscyksaG9tZXIgPSBULHRpdGxlID0gIm15byB0b3AgZW5yaWNobWVudCIsY3VzdG9tX3BhdGh3YXlzID0gbHVtaW5hbF9ncykKbXlvX2VucmljaF9yZXMKYGBgCiMjIyBMdW0gZ2VuZXMKYGBge3J9Cmx1bV9wcm90ZWluX21hcmtlcnMgPSBjKCJLSVQiKQp0b3BfbHVtICA9IHRvcF9jb3JyZWxhdGVkKGRhdGFzZXQgPSBhY2MxX2NhbmNlcl9jZWxscywgZ2VuZXMgPSBsdW1fcHJvdGVpbl9tYXJrZXJzLHRocmVzaG9sZCA9IDAuMzUpCnByaW50KCJOdW1iZXIgb2YgZ2VuZXMgPSAiICU+JSBwYXN0ZShsZW5ndGgodG9wX2x1bSkpKQptZXNzYWdlKCJOYW1lcyBvZiBnZW5lczoiKQp0b3BfbHVtICU+JSBoZWFkKDMwKQptZXNzYWdlKCJHZW5lcyB0aGF0IGFsc28gYXBlYXJlZCBpbiB0aGUgb3JpZ2luYWwgc2NvcmU6IikKaW50ZXJzZWN0KHRvcF9sdW0sb3JpZ2luYWxfbHVtX2dlbmVzKSAKYGBgCgpgYGB7cn0KbHVtX2VucmljaF9yZXMgPSBnZW5lc192ZWNfZW5yaWNobWVudChnZW5lcyA9IHRvcF9sdW0sYmFja2dyb3VuZCA9IHJvd25hbWVzKGFjYzFfY2FuY2VyX2NlbGxzKSxob21lciA9IFQsdGl0bGUgPSAibHVtIHRvcCBlbnJpY2htZW50IixjdXN0b21fcGF0aHdheXMgPSBsdW1pbmFsX2dzKQpsdW1fZW5yaWNoX3JlcwpgYGAKIyMjIHRvcCBjb3JyZWxhdGVkIHNjb3JlCmBgYHtyfQpteW9zY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1bdG9wX215byxdLDIsbWVhbikKbGVzY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1bdG9wX2x1bSxdLDIsbWVhbikKYWNjMV9jYW5jZXJfY2VsbHM9QWRkTWV0YURhdGEoYWNjMV9jYW5jZXJfY2VsbHMsbGVzY29yZS1teW9zY29yZSwidG9wX2Nvcl9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAidG9wX2Nvcl9sdW1pbmFsX292ZXJfbXlvIikKCmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsdmFycyA9ICJ0b3BfY29yX2x1bWluYWxfb3Zlcl9teW8iKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PXRvcF9jb3JfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCiMjIyAgZW5yaWNoZWQgZ2VuZXMgc2NvcmUKYGBge3J9CnJvd25hbWVzKGx1bV9lbnJpY2hfcmVzKSA9IGx1bV9lbnJpY2hfcmVzJHBhdGh3YXlfbmFtZQpsdW1fZW5yaWNoZWRfZ2VuZXMgPSBsdW1fZW5yaWNoX3Jlc1sxLCJnZW5lSUQiXSAlPiUgc3Ryc3BsaXQoc3BsaXQgPSAiLyIpICU+JSAuW1sxXV0gJT4lIGMoLixsdW1fcHJvdGVpbl9tYXJrZXJzKSAjYWRkIG9yaWdpbmFsIG1hcmtlcnMKYGBgCgpgYGB7cn0Kcm93bmFtZXMobXlvX2VucmljaF9yZXMpID0gbXlvX2VucmljaF9yZXMkcGF0aHdheV9uYW1lCm15b19lbnJpY2hlZF9nZW5lcyA9IG15b19lbnJpY2hfcmVzWzEsImdlbmVJRCJdICU+JSBzdHJzcGxpdChzcGxpdCA9ICIvIikgJT4lIC5bWzFdXSAlPiUgYyguLG15b19wcm90ZWluX21hcmtlcnMpICNhZGQgb3JpZ2luYWwgbWFya2VycwpgYGAKCmBgYHtyfQpteW9zY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1AZGF0YVtteW9fZW5yaWNoZWRfZ2VuZXMsXSwyLG1lYW4pCmxlc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbbHVtX2VucmljaGVkX2dlbmVzLF0sMixtZWFuKQphY2MxX2NhbmNlcl9jZWxscz1BZGRNZXRhRGF0YShhY2MxX2NhbmNlcl9jZWxscyxsZXNjb3JlLW15b3Njb3JlLCJlbnJpY2hlZF9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCnByaW50KAogIGRhdGEgJT4lIAogIGdncGxvdChhZXMoIHg9ZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCgojIyB7LX0KCgojIyAgMC4yIE1vc3QgY29ycmVsYXRlZCBzY29yZSB7LnRhYnNldH0KCiMjIyAgbXlvIEdlbmVzCgoKYGBge3Igd2FybmluZz1GQUxTRX0KbXlvX3Byb3RlaW5fbWFya2VycyA9IGMoIkNOTjEiLCAiVFA2MyIsIkFDVEEyIikKdG9wX215byAgPSB0b3BfY29ycmVsYXRlZChkYXRhc2V0ID0gYWNjMV9jYW5jZXJfY2VsbHMsIGdlbmVzID0gbXlvX3Byb3RlaW5fbWFya2Vycyx0aHJlc2hvbGQgPSAwLjIpCnByaW50KCJOdW1iZXIgb2YgZ2VuZXMgPSAiICU+JSBwYXN0ZShsZW5ndGgodG9wX215bykpKQptZXNzYWdlKCJOYW1lcyBvZiBnZW5lczoiKQp0b3BfbXlvICU+JSBoZWFkKDMwKQptZXNzYWdlKCJHZW5lcyB0aGF0IGFsc28gYXBlYXJlZCBpbiB0aGUgb3JpZ2luYWwgc2NvcmU6IikKaW50ZXJzZWN0KHRvcF9teW8sb3JpZ2luYWxfbXlvX2dlbmVzKSAKYGBgCgpgYGB7cn0KbXlvX2VucmljaF9yZXMgPSBnZW5lc192ZWNfZW5yaWNobWVudChnZW5lcyA9IHRvcF9teW8sYmFja2dyb3VuZCA9IHJvd25hbWVzKGFjYzFfY2FuY2VyX2NlbGxzKSxob21lciA9IFQsdGl0bGUgPSAibXlvIHRvcCBlbnJpY2htZW50IixjdXN0b21fcGF0aHdheXMgPSBsdW1pbmFsX2dzKQpteW9fZW5yaWNoX3JlcwpgYGAKIyMjICBMdW0gR2VuZXMKCmBgYHtyfQpsdW1fcHJvdGVpbl9tYXJrZXJzID0gYygiS0lUIikKdG9wX2x1bSAgPSB0b3BfY29ycmVsYXRlZChkYXRhc2V0ID0gYWNjMV9jYW5jZXJfY2VsbHMsIGdlbmVzID0gbHVtX3Byb3RlaW5fbWFya2Vycyx0aHJlc2hvbGQgPSAwLjIpCnByaW50KCJOdW1iZXIgb2YgZ2VuZXMgPSAiICU+JSBwYXN0ZShsZW5ndGgodG9wX2x1bSkpKQptZXNzYWdlKCJOYW1lcyBvZiBnZW5lczoiKQp0b3BfbHVtICU+JSBoZWFkKDMwKQptZXNzYWdlKCJHZW5lcyB0aGF0IGFsc28gYXBlYXJlZCBpbiB0aGUgb3JpZ2luYWwgc2NvcmU6IikKaW50ZXJzZWN0KHRvcF9sdW0sb3JpZ2luYWxfbHVtX2dlbmVzKSAKYGBgCgpgYGB7cn0KbHVtX2VucmljaF9yZXMgPSBnZW5lc192ZWNfZW5yaWNobWVudChnZW5lcyA9IHRvcF9sdW0sYmFja2dyb3VuZCA9IHJvd25hbWVzKGFjYzFfY2FuY2VyX2NlbGxzKSxob21lciA9IFQsdGl0bGUgPSAibHVtIHRvcCBlbnJpY2htZW50IixjdXN0b21fcGF0aHdheXMgPSBsdW1pbmFsX2dzKQpsdW1fZW5yaWNoX3JlcwpgYGAKIyMjICBjb3JyZWxhdGVkIGdlbmVzIGluIG9yaWdpbmFsIHNjb3JlCmBgYHtyfQpteW9faW50ZXJzZWN0ZWQgPSBpbnRlcnNlY3QodG9wX215byxvcmlnaW5hbF9teW9fZ2VuZXMpIApsdW1faW50ZXJzZWN0ZWQgPSBpbnRlcnNlY3QodG9wX2x1bSxvcmlnaW5hbF9sdW1fZ2VuZXMpIAptZXNzYWdlKCJnZW5lcyBpbiBteW8gc2NvcmU6IikKbXlvX2ludGVyc2VjdGVkCgptZXNzYWdlKCJnZW5lcyBpbiBsdW0gc2NvcmU6IikKbHVtX2ludGVyc2VjdGVkCgoKbXlvc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbYygiTVlMSyIsIlRQNjMiICwiQUNUQTIiLCAiREtLMyIsICJUQUdMTiIsICJDREgzIiApLF0sMixtZWFuKQpsZXNjb3JlPWFwcGx5KGFjYzFfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXUBkYXRhW2MoIktJVCIgLCJFSEYiLCAgIkxHQUxTMyIpLF0sMixtZWFuKQphY2MxX2NhbmNlcl9jZWxscz1BZGRNZXRhRGF0YShhY2MxX2NhbmNlcl9jZWxscyxsZXNjb3JlLW15b3Njb3JlLCJlbnJpY2hlZF9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCnByaW50KAogIGRhdGEgJT4lIAogIGdncGxvdChhZXMoIHg9ZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCgojIyMgZW5yaWNoZWQgZ2VuZXMKYGBge3J9CnJvd25hbWVzKGx1bV9lbnJpY2hfcmVzKSA9IGx1bV9lbnJpY2hfcmVzJHBhdGh3YXlfbmFtZQpsdW1fZW5yaWNoZWRfZ2VuZXMgPSBsdW1fZW5yaWNoX3Jlc1szLCJnZW5lSUQiXSAlPiUgc3Ryc3BsaXQoc3BsaXQgPSAiLyIpICU+JSAuW1sxXV0gJT4lIGMoLixsdW1fcHJvdGVpbl9tYXJrZXJzKSAjYWRkIG9yaWdpbmFsIG1hcmtlcnMKYGBgCgpgYGB7cn0Kcm93bmFtZXMobXlvX2VucmljaF9yZXMpID0gbXlvX2VucmljaF9yZXMkcGF0aHdheV9uYW1lCm15b19lbnJpY2hlZF9nZW5lcyA9IG15b19lbnJpY2hfcmVzWzMsImdlbmVJRCJdICU+JSBzdHJzcGxpdChzcGxpdCA9ICIvIikgJT4lIC5bWzFdXSAlPiUgYyguLG15b19wcm90ZWluX21hcmtlcnMpICNhZGQgb3JpZ2luYWwgbWFya2VycwpgYGAKCmBgYHtyfQptZXNzYWdlKCJnZW5lcyBpbiBteW8gc2NvcmU6IikKbXlvX2VucmljaGVkX2dlbmVzCgptZXNzYWdlKCJnZW5lcyBpbiBsdW0gc2NvcmU6IikKbHVtX2VucmljaGVkX2dlbmVzCgpteW9zY29yZT1hcHBseShhY2MxX2NhbmNlcl9jZWxsc0Bhc3NheXNbWyJSTkEiXV1AZGF0YVtteW9fZW5yaWNoZWRfZ2VuZXMsXSwyLG1lYW4pCmxlc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbbHVtX2VucmljaGVkX2dlbmVzLF0sMixtZWFuKQphY2MxX2NhbmNlcl9jZWxscz1BZGRNZXRhRGF0YShhY2MxX2NhbmNlcl9jZWxscyxsZXNjb3JlLW15b3Njb3JlLCJlbnJpY2hlZF9sdW1pbmFsX292ZXJfbXlvIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCgpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCnByaW50KAogIGRhdGEgJT4lIAogIGdncGxvdChhZXMoIHg9ZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215bykpICsgCiAgZ2VvbV9kZW5zaXR5KCkgCikKYGBgCgojIyMgZW5yaWNoZWQgZ2VuZXMgYW5kIGluIG9yaWdpbmFsIHNjb3JlCmBgYHtyfQpteW9fZW5yaWNoZWRfZ2VuZXMgPSBteW9fZW5yaWNoZWRfZ2VuZXNbbXlvX2VucmljaGVkX2dlbmVzICVpbiUgb3JpZ2luYWxfbXlvX2dlbmVzXQpsdW1fZW5yaWNoZWRfZ2VuZXMgPSBsdW1fZW5yaWNoZWRfZ2VuZXNbbHVtX2VucmljaGVkX2dlbmVzICVpbiUgb3JpZ2luYWxfbHVtX2dlbmVzXQoKYGBgCgpgYGB7cn0KCm1lc3NhZ2UoImdlbmVzIGluIG15byBzY29yZToiKQpteW9fZW5yaWNoZWRfZ2VuZXMKCm1lc3NhZ2UoImdlbmVzIGluIGx1bSBzY29yZToiKQpsdW1fZW5yaWNoZWRfZ2VuZXMKbXlvc2NvcmU9YXBwbHkoYWNjMV9jYW5jZXJfY2VsbHNAYXNzYXlzW1siUk5BIl1dQGRhdGFbbXlvX2VucmljaGVkX2dlbmVzLF0sMixtZWFuKQpsZXNjb3JlPWFwcGx5KGFjYzFfY2FuY2VyX2NlbGxzQGFzc2F5c1tbIlJOQSJdXUBkYXRhW2x1bV9lbnJpY2hlZF9nZW5lcyxdLDIsbWVhbikKYWNjMV9jYW5jZXJfY2VsbHM9QWRkTWV0YURhdGEoYWNjMV9jYW5jZXJfY2VsbHMsbGVzY29yZS1teW9zY29yZSwiZW5yaWNoZWRfbHVtaW5hbF9vdmVyX215byIpCkZlYXR1cmVQbG90KG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLGZlYXR1cmVzID0gImVucmljaGVkX2x1bWluYWxfb3Zlcl9teW8iKQoKZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2MxX2NhbmNlcl9jZWxscyx2YXJzID0gImVucmljaGVkX2x1bWluYWxfb3Zlcl9teW8iKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PWVucmljaGVkX2x1bWluYWxfb3Zlcl9teW8pKSArIAogIGdlb21fZGVuc2l0eSgpIAopCmBgYAoKCiMjIHstfQoKCiMgSFBWCgpPbmx5IEhNU0MgY2FuY2VyIGNlbGxzOgoKYGBge3J9CkhQVjMzX1AzID0gZnJlYWQoIi4vRGF0YS9IUFYzM19QMy50eHQiLGNvbC5uYW1lcyA9IGMoInBsYXRlIiwicmVhZHMiKSkgJT4lIGFzLmRhdGEuZnJhbWUoKQpIUFYzM19QMy5kZiA9IEhQVjMzX1AzICU+JSBtdXRhdGUoCiAgcGxhdGUgPSBnc3ViKHggPUhQVjMzX1AzJHBsYXRlLCByZXBsYWNlbWVudCA9ICIiLHBhdHRlcm4gPSAiXy4qJCIpIAogICU+JSBnc3ViKHBhdHRlcm4gPSAiLVAiLHJlcGxhY2VtZW50ID0gIi5QIikgCiAgJT4lIGdzdWIocGF0dGVybiA9ICItIixyZXBsYWNlbWVudCA9ICJfIiwpCiAgKQpIUFYzM19QMy5kZiA9IEhQVjMzX1AzLmRmICU+JSBkcGx5cjo6ZmlsdGVyKEhQVjMzX1AzLmRmJHBsYXRlICVpbiUgY29sbmFtZXMoYWNjMV9jYW5jZXJfY2VsbHMpKQpyb3duYW1lcyhIUFYzM19QMy5kZikgIDwtIEhQVjMzX1AzLmRmJHBsYXRlCkhQVjMzX1AzLmRmJHBsYXRlID0gTlVMTAoKCkhQVjMzX1AyID0gZnJlYWQoIi4vRGF0YS9IUFYzM19QMi50eHQiLGNvbC5uYW1lcyA9IGMoInBsYXRlIiwicmVhZHMiKSkgJT4lIGFzLmRhdGEuZnJhbWUoKQpIUFYzM19QMi5kZiA9IEhQVjMzX1AyICU+JSBtdXRhdGUoCiAgcGxhdGUgPSBnc3ViKHggPUhQVjMzX1AyJHBsYXRlLCByZXBsYWNlbWVudCA9ICIiLHBhdHRlcm4gPSAiXy4qJCIpIAogICU+JSBnc3ViKHBhdHRlcm4gPSAicGxhdGUyLSIscmVwbGFjZW1lbnQgPSAicGxhdGUyXyIsKQogICU+JSBnc3ViKHBhdHRlcm4gPSAiLSIscmVwbGFjZW1lbnQgPSAiXFwuIiwpCiAgKQpIUFYzM19QMi5kZiA9IEhQVjMzX1AyLmRmICU+JSBkcGx5cjo6ZmlsdGVyKEhQVjMzX1AyLmRmJHBsYXRlICVpbiUgY29sbmFtZXMoYWNjMV9jYW5jZXJfY2VsbHMpKQpyb3duYW1lcyhIUFYzM19QMi5kZikgIDwtIEhQVjMzX1AyLmRmJHBsYXRlCkhQVjMzX1AyLmRmJHBsYXRlID0gTlVMTAoKSFBWMzMgPSByYmluZChIUFYzM19QMy5kZixIUFYzM19QMi5kZikKYWNjMV9jYW5jZXJfY2VsbHMgPSBBZGRNZXRhRGF0YShvYmplY3QgPSBhY2MxX2NhbmNlcl9jZWxscyxtZXRhZGF0YSA9IEhQVjMzLGNvbC5uYW1lID0gIkhQVjMzLnJlYWRzIikKRmVhdHVyZVBsb3QoYWNjMV9jYW5jZXJfY2VsbHMsZmVhdHVyZXMgPSAiSFBWMzMucmVhZHMiLG1heC5jdXRvZmYgPSA0MCkKYGBgCmBgYHtyfQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjYzFfY2FuY2VyX2NlbGxzLHZhcnMgPSAiSFBWMzMucmVhZHMiKQpwcmludCgKICBkYXRhICU+JSAKICBnZ3Bsb3QoYWVzKCB4PUhQVjMzLnJlYWRzKSkgKyAKICBnZW9tX2RlbnNpdHkoKQopCmBgYAoK